package cn.changein.framework.modular.fileInfo.service.impl;

import cn.changein.framework.core.util.FileUtil;
import cn.changein.framework.fastDFS.AliOosUtil;
import cn.changein.framework.fastDFS.FastDFSClient;
import cn.changein.framework.kernel.model.response.ResponseData;
import cn.changein.framework.modular.fileInfo.service.FileService;
import cn.changein.framework.modular.system.entity.Dict;
import cn.changein.framework.modular.system.entity.FileInfo;
import cn.changein.framework.modular.system.service.DictService;
import cn.changein.framework.modular.system.service.FileInfoService;
import cn.changein.framework.modular.templateInfo.model.params.TemplateInfoParam;
import cn.changein.framework.modular.templateInfo.service.TemplateInfoService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class FileServiceImpl implements FileService {
    //绑定文件上传路径到uploadPath
    @Value("${file.uploadPath}")
    private String uploadPath;

    @Value("${file.domainName}")
    private String domainName;

    @Value("${file.enableOss}")
    private Boolean enableOss;

    @Autowired
    private DictService dictService;

    @Autowired
    private TemplateInfoService templateInfoService;

    private final String SYS_PATH = System.getProperty("user.dir");

    @Autowired
    private FileInfoService fileInfoService;

    @Autowired(required = false)
    FastDFSClient fastDFSClient;

    @Override
    public ResponseData uploadFile(MultipartFile file, String moduleCode, String moduleName, HttpServletRequest servletRequest, HttpServletResponse httpServletResponse) {
        String path = getUploadFilePath(moduleCode);
        if (StringUtils.isBlank(path)) {
            return ResponseData.error(moduleName + "上传文件路径不存在!");
        }
        try {
            //如果文件内容不为空，则写入上传路径
            JSONObject res = new JSONObject();
            //上传文件路径
            System.out.println("文件名称" + file.getOriginalFilename());
            //上传文件名
            String name = file.getOriginalFilename();//上传文件的真实名称
            String suffixName = name.substring(name.lastIndexOf("."));//获取后缀名
            UUID uuid = UUID.randomUUID();//文件名唯一标识
            String fileName = uuid.toString() + suffixName;


            File filepath = new File(path, fileName);
            System.out.println("文件名称" + filepath.getName());
            //将上传文件保存到一个目标文档中
            File tempFile = new File(path + File.separator + fileName);
            Integer height = null;
            Integer width = null;
            try {
                BufferedImage read = ImageIO.read(file.getInputStream());
                if (null != read) {
                    height = read.getWidth();
                    width = read.getHeight();
                }
            } catch (Exception e) {
                log.error("read image stream err", e);
            }
            String src = null;
            boolean saveFlag = false;
            //是否启用OSS
            if (enableOss) { //
                fileName = new StringBuilder("pic").append("/").append(System.currentTimeMillis()).append("-").append(fileName).toString();
                AliOosUtil.upload(fileName, file.getInputStream());
                //修改域名
                src = domainName + fileName;
                saveFlag = true;
            } else if (fastDFSClient != null) { //fastDfs
                try {
                    src = fastDFSClient.uploadFileWithMultipart(file);
                    saveFlag = true;
                } catch (Exception e) {
                    log.error("", e);
                }
            } else { //本地
                file.transferTo(tempFile);
                saveFlag = saveFileInfo(filepath.getName(), moduleCode, moduleName, suffixName, uuid.toString(), tempFile);
            }
            if (saveFlag) {
                res.put("src", src != null ? src : "/file/" + uploadPath + "/" + moduleCode + "/" + filepath.getName());
                res.put("url", res.get("src"));
                res.put("fileName", filepath.getName());
                res.put("uuid", uuid);
                log.info("res里面的值：" + res.toJSONString());
                if ("pdf".equals(suffixName)) {
                    httpServletResponse.setHeader("content-disposition", "attachment;filename=" + filepath.getName());
                }
                res.put("width", height);
                res.put("height", width);
                return ResponseData.success(res);
            } else {
                return ResponseData.error("文件上传失败");
            }
        } catch (IOException e) {

        }
        return ResponseData.error("文件上传失败");

    }


    /*

     * @Description //TODO 模板上传
     * @Date 2020-11-27 10:06
     * @MethodName templateUploadFile
     * @Param [file, templateInfoParam, servletRequest, httpServletResponse]
     * @return cn.changein.framework.kernel.model.response.ResponseData
     **/
    @Override
    public ResponseData templateUploadFile(MultipartFile file, TemplateInfoParam templateInfoParam, HttpServletRequest servletRequest, HttpServletResponse httpServletResponse) {
        String templatePath = getUploadFilePath("TEMPLATE");
        if (StringUtils.isBlank(templatePath)) {
            return ResponseData.error("模板上传文件路径不存在!");
        }
        try {
            //上传文件路径
            System.out.println("文件名称" + file.getOriginalFilename());
            //上传文件名
            String filename = file.getOriginalFilename();//上传文件的真实名称
            String suffixName = filename.substring(filename.lastIndexOf("."));//获取后缀名
            File filepath = new File(templatePath, filename);
            System.out.println("文件名称" + filepath.getName());
            //将上传文件保存到一个目标文档中
            File tempFile = new File(templatePath + File.separator + filename);
            if (tempFile.exists()) {
                tempFile.delete();
            }
            file.transferTo(tempFile);
            boolean saveFlag = templateInfoService.saveOrUpdateTemplateInfo(templateInfoParam, filename, tempFile);
            if (saveFlag) {
                if ("pdf".equals(suffixName)) {
                    httpServletResponse.setHeader("content-disposition", "attachment;filename=" + filepath.getName());
                }
                return ResponseData.success();
            } else {
                return ResponseData.error("文件上传失败");
            }
        } catch (IOException e) {

        }
        return ResponseData.error("文件上传失败");

    }

    /*

     * @Description //TODO 下载其他文件
     * @Date 2020-11-27 17:25
     * @MethodName downLoadFile
     * @Param [moduleCode, moduleName, fileName, servletRequest, httpServletResponse]
     * @return void
     **/
    @Override
    public void downLoadFile(String moduleCode, String moduleName, String fileName, HttpServletRequest servletRequest, HttpServletResponse httpServletResponse) throws FileNotFoundException {
        FileInfo fileInfo = getFileInfoByModuleAndFileName(moduleCode, moduleName, fileName);
        if (fileInfo != null) {
            try {
                String filePath = fileInfo.getFilePath();
                File file = new File(filePath);
                if (file.exists()) {
                    FileUtil.downloadFile(file, httpServletResponse);
                } else {
                    throw new FileNotFoundException();
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /**
     * 在线预览文件
     *
     * @param finalName 文件路径
     * @param request
     * @param response
     */
    @Override
    public void previewPdfFile(String finalName, HttpServletRequest request, HttpServletResponse response) {
    }


    private FileInfo getFileInfoByModuleAndFileName(String moduleCode, String moduleName, String fileName) {
        FileInfo fileInfo = fileInfoService.getFileInfoByModuleAndFileName(moduleCode, moduleName, fileName);
        return fileInfo;
    }

    private boolean saveFileInfo(String fileName, String moduleCode, String moduleName, String suffixName, String uuid, File tempFile) {
        FileInfo fileInfo = new FileInfo();
        fileInfo.setModuleCode(moduleCode);
        fileInfo.setModuleName(moduleName);
        fileInfo.setFileSuffix(suffixName);
        fileInfo.setFileName(fileName);
        fileInfo.setSrcPath(uploadPath + "\\" + moduleCode + "\\" + fileName);
        fileInfo.setFinalName(uuid);
        fileInfo.setFilePath(tempFile.getPath());
        fileInfo.setFileSizeKb(tempFile.length() / 1000);
        return fileInfoService.saveFileInfo(fileInfo);
    }


    /*

     * @Description //TODO 根据获取文件上传路径
     * @Date 2020-11-26 16:36
     * @MethodName getFilePath
     * @Param [module]
     * @return void
     **/
    private String getUploadFilePath(String moduleCode) {
        String path = "";
        //根据module 获取类型为FILE_UPLOAD_MODULE的字典信息
        List<Dict> dicts = dictService.getBaseMapper().getDicInfoForFileUploadModuleType(moduleCode);
        if (dicts.size() > 0) {
            path = SYS_PATH + File.separator + uploadPath + File.separator + moduleCode;
            File file = new File(path);
            if (!file.exists() && !file.isDirectory()) {
                file.mkdirs();
            }
        }
        return path;
    }

}
